package torres.map;

import java.io.File;
import java.util.Scanner;
import torres.map.tile.*;
import torres.item.Item;
import torres.item.ItemManager;
import torres.map.effect.*;

/**
 * @author Torres
 * Generates a Map instance from a .map file.
 */
public class MapGenerator {
	
	/**
	 * Creates a Tile[][] that is a representation of the specified .map file.
	 * @param file The .map file from which the Tile[][] is being generated.
	 * @return The Tile[][] that is a representation of the specified .map file.
	 */
	public static Tile[][] generate(File file) {
		
		Scanner reader = null;
		Tile tiles[][] = null;
		
		try{
			reader = new Scanner(file);
			int row = reader.nextInt();
			int column = reader.nextInt();
			tiles = new Tile[row][column];
			
			//parse the map file for each tile's terrain type
			int line = 0;
			while(line < row) {
				for(int col = 0; col < column; col++) {
					
					char c = reader.next().toUpperCase().charAt(0);
					switch(c) {
					
						case 'G':
							tiles[line][col] = new ConcreteTile(Grass.getInstance());
							break;
						case 'M':
							tiles[line][col] = new ConcreteTile(Mountain.getInstance());
							break;
						case 'W':
							tiles[line][col] = new ConcreteTile(Water.getInstance());
							break;
						default:
							System.out.println("BAD, BAD, BAD....");
					}
				}
				line++;
			}
			
			//parse the map file for any decals
			reader.next();
			line = 0;
			while(line < row) {
				for(int col = 0; col < column; col++) {
					
					char c = reader.next().charAt(0);
					switch(c) {
					
						case '*':
							tiles[line][col] = new GoldStar(tiles[line][col]);
							break;
						case '+':
							tiles[line][col] = new RedCross(tiles[line][col]);
							break;
						case '@':
							tiles[line][col] = new SkullCrossbones(tiles[line][col]);
							break;
						case '-':
							tiles[line][col] = new Biohazard(tiles[line][col]);
							break;
					}
				}
				line++;
			}
			
			//parse the map file for any items
			reader.next();
			line = 0;
			ItemManager itemManager = ItemManager.getInstance();
			while(line < row) {
				for(int col = 0; col < column; col++) {
					Item item;
					if(!reader.hasNextInt()) {
						reader.next();
						continue;
					}
					int itemID = reader.nextInt();
					if(itemID < 200) //all Takeable IDs are less than this value
						item = itemManager.getTakeableItem(itemID);
					else if(itemID < 300) //all Equippable IDs are less than this value
						item = itemManager.getEquippableItem(itemID);
					else if(itemID < 400) //all Interactive IDs are less than this value
						item = itemManager.getInteractiveItem(itemID);
					else if(itemID < 500) //all OneShot IDs are less than this value
						item = itemManager.getTrapItem(itemID);
					else if(itemID < 600) 
						item = itemManager.getOneShotItem(itemID);
					else //it must be an Obstacle
						item = itemManager.getObstacleItem(itemID);
					tiles[line][col].addItem(item);
				}
				line++;
			}
			
			//parse the map file for any area effects
			reader.next();
			line = 0;
			while(line < row) {
				for(int col = 0; col < column; col++) {
					
					char c = reader.next().charAt(0);
					switch(c) {
					
						case 'H':
							tiles[line][col].addEffect(new HealDamage());
							break;
						case 'P':
							tiles[line][col].addEffect(new TakeDamage());
							break;
						case 'D':
							tiles[line][col].addEffect(new InstantDeath());
							break;
						case 'L':
							tiles[line][col].addEffect(new LevelUp());
							break;
					}
				}
				line++;
			}
			
			return tiles;
		}
		catch(Exception e) {
			e.printStackTrace();
			System.out.println(e.toString() + "-> Scream!!!!" );
		}
		finally {
			reader.close();
		}
		return tiles;
	}
	
}
